package com.ocom.payconfig.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ocom.common.entity.card.EntityXfAccountInfo;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.entity.human.EntityDeptInfo;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.entity.payconfig.EntityXfMealLeave;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.request.payconfig.AddSubsidyDataResquest;
import com.ocom.common.request.payconfig.NotMealRequest;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.StringUtils;
import com.ocom.common.vo.payconfig.NotMealVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.dao.IDaoPersonnelInfo;
import com.ocom.payconfig.service.PersonnelInfoService;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Slf4j
@Service
public class PersonnelInfoServiceImpl extends JoinServiceImpl<IDaoPersonnelInfo, EntityPersonnelInfo> implements PersonnelInfoService {

    @Autowired
    private IDaoPersonnelInfo iDaoPersonnelInfo;

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Override
    public EntityPersonnelInfo getOnePersonInfo(Long comId, String pCode, String pName) {
        QueryWrapper<EntityPersonnelInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("com_id",comId);
        queryWrapper.eq("p_code",pCode);
        queryWrapper.eq("p_name",pName);
        return iDaoPersonnelInfo.selectOne(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    public EntityPersonnelInfo getOnePersonInfo(Long comId, Long pId) {
        QueryWrapper<EntityPersonnelInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("com_id",comId);
        queryWrapper.eq("p_id",pId);
        queryWrapper.eq("status",0);
        return this.getOne(queryWrapper);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityPersonnelInfo> selectPerson(Long comId, AddSubsidyDataResquest addSubsidyDataResquest) {
        QueryWrapper<EntityPersonnelInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("com_id",comId);
        queryWrapper.eq("status",0);
        if (StringUtils.isNotEmpty(addSubsidyDataResquest.getDeptIds())){
            String[] arr=addSubsidyDataResquest.getDeptIds().split(",");
            queryWrapper.in("dept_id",arr);
        }
        if (StringUtils.isNotEmpty(addSubsidyDataResquest.getPCode())){
            queryWrapper.eq("p_code",addSubsidyDataResquest.getPCode());
        }
        if (StringUtils.isNotEmpty(addSubsidyDataResquest.getPName())){
            queryWrapper.like("p_name",addSubsidyDataResquest.getPName());
        }


        if(addSubsidyDataResquest.getPTags()!=null && addSubsidyDataResquest.getPTags().size()>0){

            queryWrapper.apply( " p_tags IS NOT NULL " );

            List<String> finalDates = addSubsidyDataResquest.getPTags();
            //日期范围查询
            queryWrapper.and(wrapper -> {
                for (String info : finalDates) {
                    wrapper.or().like("p_tags", ","+info+",");
                }
            });
        }

        return this.list(queryWrapper);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public List<EntityPersonnelInfo> selectPersonVo(Long comId, AddSubsidyDataResquest addSubsidyDataResquest) {
        String[] arr=addSubsidyDataResquest.getDeptIds().split(",");
        addSubsidyDataResquest.setDeptIdList(Arrays.asList(arr));
        return iDaoPersonnelInfo.selectPersonVo(addSubsidyDataResquest);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityPersonnelInfo> selectPersonAndAccount(Long comId, List<Integer> accType, List<String> deptIdList, List<String> pTags) {
        return iDaoPersonnelInfo.selectPersonAndAccount(comId, accType, deptIdList, pTags);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public EntityPersonnelInfo getDataByPerson(Long comId, String pCode) {
        QueryWrapper<EntityPersonnelInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("com_id",comId);
        queryWrapper.eq("p_code",pCode);
        queryWrapper.orderByDesc("p_id");
        queryWrapper.last("limit 1");
        return iDaoPersonnelInfo.selectOne(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId", isMaster = MasterSlaveEnum.MASTER)
    public List<EntityPersonnelInfo> selectPerson(Long comId, String pCode, String pName) {
        QueryWrapper<EntityPersonnelInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("com_id", comId);
        if (!CommonUtil.isNull(pCode)) {
            queryWrapper.eq("p_code", pCode);
        }
        if (!CommonUtil.isNull(pName)) {
            queryWrapper.eq("p_name", pName);
        }
        queryWrapper.eq("status", 0);
        queryWrapper.orderByDesc("update_time");
        return this.list(queryWrapper);
    }
    public List<Map<String, Object>> selectPersonByFee(Long comId, int deptId,String pCode, String pName ) {
        QueryWrapper<EntityPersonnelInfo> queryWrapper = Wrappers.query();
        queryWrapper.select("p_id AS pId","dept_id AS deptId");
        queryWrapper.eq("com_id", comId);
        queryWrapper.eq("status", 0);
        if (deptId != 0) {
            queryWrapper.eq("dept_id", deptId);
        }
        if (StringUtils.isNotEmpty(pCode)) {
            queryWrapper.eq("p_code", pCode);
        }
        if (StringUtils.isNotEmpty(pName)) {
            queryWrapper.like("p_name", pName);
        }
        return this.listMaps(queryWrapper);
    }


    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE, companyId = "comId")
    public EntityPersonnelInfo selectPersonByPCode(Long comId, String pCode) {
        QueryWrapper<EntityPersonnelInfo> query = Wrappers.query();
        query.select("p_id");
        query.eq("com_id", comId);
        query.eq("p_code", pCode).last("LIMIT 1");
        EntityPersonnelInfo info = this.getOne(query);
        return info;
    }


    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityPersonnelInfo> totalNumberPerson(Long comId) {
        return iDaoPersonnelInfo.totalNumberPerson(comId);
    }


    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB ,isMaster = MasterSlaveEnum.SLAVE)
    public Page<NotMealVo> getMealPerReports(Long companyId, NotMealRequest request) {

        JoinLambdaWrapper<EntityPersonnelInfo> queryWrapper =  new JoinLambdaWrapper<>(EntityPersonnelInfo.class);

        queryWrapper.selectAs((cb) -> {
            cb.add(" personnel_info.com_id ","comId",false);
            cb.add(" personnel_info.p_id ","pId",false);
            cb.add(" personnel_info.p_code ","pCode",false);
            cb.add(" personnel_info.p_name ","pName",false);
        });

        queryWrapper.eq(EntityPersonnelInfo::getComId,request.getComId());
        queryWrapper.eq(EntityPersonnelInfo::getStatus,0);
        if(request.getPName()!=null){
            queryWrapper.eq(EntityPersonnelInfo::getPName,request.getPName());
        }
        if(request.getPCode()!=null){
            queryWrapper.eq(EntityPersonnelInfo::getPCode,request.getPCode());
        }
        if(request.getDeptIds().size()>0){
            queryWrapper.in(EntityPersonnelInfo::getDeptId,request.getDeptIds());
        }


        queryWrapper.leftJoin(EntityDeptInfo.class, EntityDeptInfo::getDeptId, EntityPersonnelInfo::getDeptId)
                .joinAnd(EntityDeptInfo::getComId,EntityPersonnelInfo::getComId,0)
                .selectAs((cb) -> {
                    cb.add(" dept_info.dept_id ","deptId",false);
                    cb.add(" dept_info.dept_name ","deptName",false);
                    cb.add(request.getMealDate(),"mealDate",true);
                    cb.add(request.getMealNo(),"mealNo",true);
                }).end();

        queryWrapper.leftJoin(EntityXfMealLeave.class, EntityXfMealLeave::getComId, EntityPersonnelInfo::getComId)
                .joinAnd(EntityXfMealLeave::getpId,EntityPersonnelInfo::getPId,0)
                .joinAnd(EntityXfMealLeave::getMealDate,request.getMealDate(),0)
                .joinAnd(EntityXfMealLeave::getMealNo,request.getMealNo(),0)
                .func(w -> {
                    w.eq(EntityXfMealLeave::getIsLeave,0).or().isNull(EntityXfMealLeave::getIsLeave);
                })
                .end();

        queryWrapper.leftJoin(EntityXfRecordProcess.class, EntityXfRecordProcess::getComId, EntityPersonnelInfo::getComId)
                .joinAnd(EntityXfRecordProcess::getPId,EntityPersonnelInfo::getPId,0)
                .joinAnd(EntityXfRecordProcess::getMealDate,request.getMealDate(),0)
                .joinAnd(EntityXfRecordProcess::getMealNo,request.getMealNo(),0)
                .joinAnd(EntityXfRecordProcess::getPayState,1,0)
                .joinAnd(EntityXfRecordProcess::getIfRefund,0,0)
                .func(w -> {
                    w.isNull(EntityXfRecordProcess::getId);
                })
                .end();

        if(request.getAccTypeId()!=null && request.getAccTypeId()>0) {
            queryWrapper.leftJoin(EntityXfAccountInfo.class, EntityXfAccountInfo::getComId, EntityPersonnelInfo::getComId)
                    .joinAnd(EntityXfAccountInfo::getPId, EntityPersonnelInfo::getPId, 0)
                    .func(w -> {
                        w.eq(EntityXfAccountInfo::getAccTypeId, request.getAccTypeId());
                    })
                    .end();
        }

        Page<NotMealVo> page1 = new Page<>(request.getPage(), request.getSize());
        return this.joinPage(page1,queryWrapper, NotMealVo.class);

    }

}
